from tkinter import StringVar, DISABLED, PhotoImage, HORIZONTAL, Tk, Menu, END
from tkinter.messagebox import showinfo, showerror
from tkinter.ttk import Label, Entry, Button, Scale
import pyperclip
import json
import urllib.request
import ssl


def rightKey(self, event, editor):
    self.menubar = Menu(self, tearoff=False)  # 创建一个菜单
    self.menubar.add_command(label='复制', command=lambda: editor.event_generate("<<Copy>>"))
    self.menubar.add_command(label='粘贴', command=lambda: editor.event_generate('<<Paste>>'))
    self.menubar.add_command(label='剪切', command=lambda: editor.event_generate("<<Cut>>"))
    self.menubar.post(event.x_root, event.y_root)


def idcard_verification(idcard=''):
    appcode = '88fdcd016e554d05ba8d79f35a4f19b7'
    url = f'https://jisuidcard.market.alicloudapi.com/idcard/query?idcard={idcard}'
    request = urllib.request.Request(url)
    request.add_header('Authorization', 'APPCODE ' + appcode)
    request.add_header('Content-Type', 'application/json; charset=UTF-8')
    ctx = ssl.create_default_context()
    ctx.check_hostname = False
    ctx.verify_mode = ssl.CERT_NONE
    try:
        response = urllib.request.urlopen(request, context=ctx)
        content = response.read()
        if content:
            return json.loads(content)
    except Exception as e:
        showerror("系统消息", f"服务异常，联系Andy：13170644441\n\n{e}")


class IDCheckGUI(Tk):
    def __init__(self):
        super().__init__()
        # 数据参数定义
        self.login_image = PhotoImage(file="img/left.png")
        self.var_input = StringVar()
        self.var_valid = StringVar()
        self.var_sex = StringVar()
        self.var_date = StringVar()
        self.var_area = StringVar()
        # 窗体设置+数据参数及方法绑定
        self.title("身份证信息校验系统")
        self.iconbitmap('./img/title.ico')
        self.geometry("727x472+10+10")  # w*h+x+y
        self.resizable(0, 0)
        self["bg"] = "whitesmoke"
        self.setup_UI()

    def setup_UI(self):
        font10 = ("微软雅黑", 10, "bold")
        font18 = ("微软雅黑", 18, "bold")
        x = [350, 430]
        y = [170, 165]
        w, h = 60, 38
        # 左侧图片
        Label(self, image=self.login_image).place(x=5, y=5)
        # 输入信息
        Label(self, text="请输入身份证号码:", font=font10).place(x=x[0], y=20)
        # Entry(self, textvariable=self.var_input, font=font18).place(x=x[0], y=70)
        ent = Entry(self, textvariable=self.var_input, font=font18)
        ent.place(x=x[0], y=70)
        ent.bind("<Button-3>", lambda x1: rightKey(self, x1, ent))  # 绑定右键鼠标事件

        # 验证按钮
        self.bind('<Return>', self.get_info)
        Button(self, text="校验", command=self.get_info).place(x=660, y=70, width=60, height=38)
        # 具体信息
        Label(self, text="是否有效：").place(x=x[0], y=y[0])
        Entry(self, state=DISABLED, textvariable=self.var_valid, font=font10).place(x=x[1], y=y[1], width=w)
        Label(self, text="性     别：").place(x=x[0], y=y[0] + 50)
        Entry(self, state=DISABLED, textvariable=self.var_sex, font=font10).place(x=x[1], y=y[1] + 50, width=w)
        Label(self, text="出生日期：").place(x=x[0], y=y[0] + 50 * 2)
        Entry(self, state=DISABLED, textvariable=self.var_date, font=font10).place(x=x[1], y=y[1] + 50 * 2,
                                                                                   width=w + 140)
        Label(self, text="所  在  地：").place(x=x[0], y=y[0] + 50 * 3)
        ent2 = Entry(self, textvariable=self.var_area, font=font10)
        ent2.place(x=x[1], y=y[1] + 50 * 3, width=w + 230)
        ent2.bind("<Button-3>", lambda x1: rightKey(self, x1, ent2))  # 绑定右键鼠标事件

        Label(self, text="透  明  度：").place(x=x[0], y=y[0] + 50 * 4)
        Scale(self, from_=0, to=0.9, orient=HORIZONTAL, command=self.set_alpha).place(x=x[1], y=y[1] + 50 * 4)
        Label(self, text="备     注：[1].所在地会自动复制，可直接粘贴。\n              [2].回车键等同于鼠标点击检验按钮").place(x=x[0], y=y[0] + 50 * 5)

    def set_alpha(self, v):
        self.attributes("-alpha", 1 - float(v))

    # enter调用
    def btn_click_enter(self, s):
        self.get_info()

    def get_info(self, no=None):
        self.var_valid.set('')
        self.var_sex.set('')
        self.var_date.set('')
        self.var_area.set('')
        id_number = self.var_input.get()
        if len(id_number) == 18:
            check_code_xi = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]  # 每个位上乘的系数列表
            check_code = ["1", "0", "x", "9", "8", "7", "6", "5", "4", "3", "2"]  # 返回的校验码列表
            tmp_sum = sum([int(id_number[:17][i]) * check_code_xi[i] for i in range(len(check_code_xi))])
            check_code = check_code[tmp_sum % 11]
            if check_code == id_number[17]:
                r_data = idcard_verification(id_number)
                if r_data:
                    self.var_valid.set('有效')
                    self.var_sex.set(r_data['result']['sex'])
                    self.var_date.set(r_data['result']['birth'])
                    self.var_area.set(r_data['result']['area'].replace(' ', ''))
                    pyperclip.copy(r_data['result']['area'].replace(' ', ''))
            else:
                self.var_valid.set('无效')
        else:
            showinfo("系统消息", "身份证格式不对，请重新输入！")


if __name__ == '__main__':
    check_gui = IDCheckGUI()
    check_gui.mainloop()
